package com.cyan.note.controller;

import com.cyan.note.common.ApiResult;
import com.cyan.note.dto.admin.SystemStatsResponse;
import com.cyan.note.service.SystemMonitorService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

/**
 * 超级管理员 - 系统监控控制器
 * 严格按照RBAC权限控制，只有超级管理员可以访问
 * 严格遵循数据隔离原则，只能查看系统级统计数据
 * 
 * @author ZhangzhenYu
 * @since 2025-01-14
 */
@Slf4j
@RestController
@RequestMapping("/api/admin/system")
@RequiredArgsConstructor
public class AdminSystemController {

    private final SystemMonitorService systemMonitorService;

    /**
     * 获取系统整体统计数据
     * 权限：仅超级管理员
     * 说明：仅包含系统级统计，不包含任何业务数据
     */
    @GetMapping("/stats")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<SystemStatsResponse> getSystemStats() {
        try {
            log.info("超级管理员获取系统整体统计数据");
            SystemStatsResponse stats = systemMonitorService.getSystemStats();
            return ApiResult.success("获取系统统计数据成功", stats);
        } catch (Exception e) {
            log.error("获取系统统计数据失败", e);
            return ApiResult.error("获取系统统计数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取店铺统计数据（仅数量统计）
     * 权限：仅超级管理员
     */
    @GetMapping("/shop-stats")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<SystemStatsResponse.ShopStats> getShopStats() {
        try {
            log.info("超级管理员获取店铺统计数据");
            SystemStatsResponse.ShopStats shopStats = systemMonitorService.getShopStats();
            return ApiResult.success("获取店铺统计数据成功", shopStats);
        } catch (Exception e) {
            log.error("获取店铺统计数据失败", e);
            return ApiResult.error("获取店铺统计数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户统计数据（仅数量统计）
     * 权限：仅超级管理员
     */
    @GetMapping("/user-stats")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<SystemStatsResponse.UserStats> getUserStats() {
        try {
            log.info("超级管理员获取用户统计数据");
            SystemStatsResponse.UserStats userStats = systemMonitorService.getUserStats();
            return ApiResult.success("获取用户统计数据成功", userStats);
        } catch (Exception e) {
            log.error("获取用户统计数据失败", e);
            return ApiResult.error("获取用户统计数据失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统运行状态
     * 权限：仅超级管理员
     */
    @GetMapping("/status")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<SystemStatsResponse.SystemStatus> getSystemStatus() {
        try {
            log.info("超级管理员获取系统运行状态");
            SystemStatsResponse.SystemStatus systemStatus = systemMonitorService.getSystemStatus();
            return ApiResult.success("获取系统状态成功", systemStatus);
        } catch (Exception e) {
            log.error("获取系统状态失败", e);
            return ApiResult.error("获取系统状态失败: " + e.getMessage());
        }
    }

    /**
     * 检查数据库连接状态
     * 权限：仅超级管理员
     */
    @GetMapping("/database-status")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<String> getDatabaseStatus() {
        try {
            log.info("超级管理员检查数据库连接状态");
            String status = systemMonitorService.checkDatabaseStatus();
            return ApiResult.success("数据库状态检查完成", status);
        } catch (Exception e) {
            log.error("数据库状态检查失败", e);
            return ApiResult.error("数据库状态检查失败: " + e.getMessage());
        }
    }

    /**
     * 系统健康检查（简化版）
     * 权限：仅超级管理员
     */
    @GetMapping("/health")
    @PreAuthorize("hasRole('SUPER_ADMIN')")
    public ApiResult<SystemHealth> getSystemHealth() {
        try {
            log.info("超级管理员获取系统健康状态");
            
            SystemHealth health = new SystemHealth();
            
            // 检查数据库状态
            String dbStatus = systemMonitorService.checkDatabaseStatus();
            health.setDatabaseHealth("connected".equals(dbStatus));
            
            // 检查内存使用率
            SystemStatsResponse.SystemStatus systemStatus = systemMonitorService.getSystemStatus();
            if (systemStatus.getJvmInfo() != null) {
                double memoryUsage = systemStatus.getJvmInfo().getMemoryUsage();
                health.setMemoryHealth(memoryUsage < 85.0); // 内存使用率低于85%为健康
                health.setMemoryUsage(memoryUsage);
            }
            
            // 系统运行时长（超过1分钟为健康）
            long uptimeMinutes = systemStatus.getUptime() / 1000 / 60;
            health.setSystemHealth(uptimeMinutes > 1);
            health.setUptimeMinutes(uptimeMinutes);
            
            // 整体健康状态
            health.setOverallHealth(health.isDatabaseHealth() && health.isMemoryHealth() && health.isSystemHealth());
            
            return ApiResult.success("系统健康检查完成", health);
        } catch (Exception e) {
            log.error("系统健康检查失败", e);
            return ApiResult.error("系统健康检查失败: " + e.getMessage());
        }
    }

    /**
     * 系统健康状态内部类
     */
    public static class SystemHealth {
        private boolean overallHealth;
        private boolean databaseHealth;
        private boolean memoryHealth;
        private boolean systemHealth;
        private double memoryUsage;
        private long uptimeMinutes;
        
        // Getters and Setters
        public boolean isOverallHealth() { return overallHealth; }
        public void setOverallHealth(boolean overallHealth) { this.overallHealth = overallHealth; }
        
        public boolean isDatabaseHealth() { return databaseHealth; }
        public void setDatabaseHealth(boolean databaseHealth) { this.databaseHealth = databaseHealth; }
        
        public boolean isMemoryHealth() { return memoryHealth; }
        public void setMemoryHealth(boolean memoryHealth) { this.memoryHealth = memoryHealth; }
        
        public boolean isSystemHealth() { return systemHealth; }
        public void setSystemHealth(boolean systemHealth) { this.systemHealth = systemHealth; }
        
        public double getMemoryUsage() { return memoryUsage; }
        public void setMemoryUsage(double memoryUsage) { this.memoryUsage = memoryUsage; }
        
        public long getUptimeMinutes() { return uptimeMinutes; }
        public void setUptimeMinutes(long uptimeMinutes) { this.uptimeMinutes = uptimeMinutes; }
    }
}